
package cn.uncode.rpc.registry.support;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

import cn.uncode.rpc.common.message.Messages;
import cn.uncode.rpc.core.URL;
import cn.uncode.rpc.exception.FrameworkException;
import cn.uncode.rpc.registry.Registry;
import cn.uncode.rpc.registry.RegistryFactory;





/**
 * 
 * Create and cache registry.
 */

public abstract class AbstractRegistryFactory implements RegistryFactory {

    private static final ConcurrentHashMap<String, Registry> REGISTRIES = new ConcurrentHashMap<String, Registry>();

    private static final ReentrantLock LOCK = new ReentrantLock();

    @Override
    public Registry getRegistry(URL url) {
        String registryUri = url.getUri();
        try {
            LOCK.lock();
            Registry registry = REGISTRIES.get(registryUri);
            if (registry != null) {
                return registry;
            }
            registry = createRegistry(url);
            if (registry == null) {
                throw new FrameworkException(Messages.getString("RuntimeError.CreateRegistryError", url.toString()));
            }
            REGISTRIES.put(registryUri, registry);
            return registry;
        } catch (Exception e) {
        	throw new FrameworkException(Messages.getString("RuntimeError.CreateRegistryError", url.toString()));
        } finally {
            LOCK.unlock();
        }
    }

    protected abstract Registry createRegistry(URL url);
}
